package com.github.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.github.api.auth.constant.SysTypeEnum;
import com.github.api.auth.dto.AuthAccountDTO;
import com.github.api.auth.feign.AccountFeignClient;
import com.github.api.auth.vo.AuthAccountVO;
import com.github.api.leaf.feign.SegmentFeignClient;
import com.github.api.user.vo.UserApiVO;
import com.github.common.cache.constant.UserCacheNames;
import com.github.common.core.exception.MallXHcloudException;
import com.github.common.core.response.ResponseEnum;
import com.github.common.core.response.ServerResponseEntity;
import com.github.common.core.util.IpHelper;
import com.github.common.database.vo.PageVO;
import com.github.user.dto.UserRegisterDTO;
import com.github.user.mapper.UserMapper;
import com.github.user.model.User;
import com.github.user.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 用户表
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private AccountFeignClient accountFeignClient;

    @Resource
    private SegmentFeignClient segmentFeignClient;





    @Override
    public PageVO<UserApiVO> page(PageDTO pageDTO) {
        //todo:待补全（mybatis-plus分页）
        Page page=new Page();



        return null;
    }


    @Override
    @Cacheable(cacheNames = UserCacheNames.USER_INFO, key = "#userId")
    public UserApiVO getByUserId(Long userId) {
//        根据用户表id获取用户表
        return userMapper.getByUserId(userId);
    }

    @Override
    @CacheEvict(cacheNames = UserCacheNames.USER_INFO, key = "#user.userId")//更新时需要清除缓存
    public void update(User user) {
        userMapper.update(user);
    }

    @Override
    public List<UserApiVO> getUserByUserIds(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)){
            return new ArrayList<UserApiVO>();
        }
        return userMapper.getUserByUserIds(userIds);
    }

    @Override
    //@GlobalTransactional：分布式事务管理，依赖于seata服务，适用于横跨多个服务的事务管理。
    // @Transactional：适用于单个服务内部的事务管理，确保单个数据库操作的一致性。
//    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)//todo:后面优化成分布式事务
    public Long save(UserRegisterDTO param) {
        this.checkRegisterInfo(param);
        ServerResponseEntity<Long> segmentIdResponse = segmentFeignClient.getSegmentId(User.DISTRIBUTED_ID_KEY);//拿到分布式id
        if (segmentIdResponse.isSuccess()){
            throw new MallXHcloudException(ResponseEnum.EXCEPTION);
        }
        Long userId = segmentIdResponse.getData();//分布式id
        param.setUserId(userId);
        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        authAccountDTO.setCreateIp(IpHelper.getIpAddr());//这里可以拿到用户ip：：：todo:其他项目可采用
        authAccountDTO.setPassword(param.getPassword());
        authAccountDTO.setIsAdmin(0);//非管理员
        authAccountDTO.setSysType(SysTypeEnum.ORDINARY.value());//平台用户系统
        authAccountDTO.setUsername(param.getUserName());
        authAccountDTO.setStatus(1);//正常账户|非拉黑
        authAccountDTO.setTenantId(userId);

        //先保存统一账户信息，再保存用户信息
        ServerResponseEntity<Long> severResponse = accountFeignClient.save(authAccountDTO);
        //抛异常回滚
        if (!severResponse.isSuccess()){
            throw new MallXHcloudException(severResponse.getMsg());
        }

        User user = new User();
        user.setUserId(userId);
        user.setPic(param.getImg());
        user.setNickName(param.getNickName());
        user.setStatus(1);
        //这里需要保存以后才有用户id--自动生成
        userMapper.save(user);


        return severResponse.getData();
    }




    private void checkRegisterInfo(UserRegisterDTO userRegisterDTO) {
        ServerResponseEntity<AuthAccountVO> responseEntity = accountFeignClient.getByUsernameAndSysType(userRegisterDTO.getUserName(), SysTypeEnum.ORDINARY);
        if (!responseEntity.isSuccess()) {
            throw new MallXHcloudException(responseEntity.getMsg());
        }
        if (Objects.nonNull(responseEntity.getData())) {
            throw new MallXHcloudException("用户名已存在");
        }
    }











}
